#ifndef INTERFACE_H
#define INTERFACE_H

#include <QtGui\QWidget>
#include <QtGui\QPushButton>
#include <QtGui\QSlider>
#include <QtGui\QComboBox>
#include <QtGui\QDialog>
#include <QtGui\QTextEdit>
#include <QtGui\QCheckBox>
#include <QtGui\QSpinBox>
#include <QtGui\QLabel>
#include <QTimer>
#include "math_model.h"

#include "common.h"


class RealNumTextEdit : public QTextEdit
{
  Q_OBJECT
public:
  RealNumTextEdit(QWidget* parent = NULL);
  RealNumTextEdit(double val, QWidget* parent = NULL);
 
  void setValue(double val);

  void keyPressEvent(QKeyEvent *event);
  QSize sizeHint() const;

signals:
  void enterPressed();
};

class InputStringDialog : public QDialog
{
  Q_OBJECT
public:
  InputStringDialog(QString title, QWidget* parent = NULL);

  void setString(QString data);
  QString getString() const;
signals:
  void stringChanged();
private slots:
  void set();
private:
  QPushButton* setButton;
  QString str;
  RealNumTextEdit* textEdit;
};

class AnimationScroller : public QWidget
{
  Q_OBJECT

public:
  AnimationScroller(QWidget* parent = NULL, unsigned _framesNumber = 0);
  ~AnimationScroller();

signals:
  void animationAtFrame(int frameNumber);
public slots:
  void newAnimationSpeed(int mult);
public slots:
  void animationStart();
  void animationStop();
  void animationPause();
  void newFrame();
  void moveToFrame(int frameNumber);
private:

  QSlider* slider;
  QPushButton* start;
  QPushButton* stop;
  QPushButton* pause;

  QTimer* timer;

  unsigned m_mult;
  unsigned framesNumber;

  static const unsigned INTERVAL;

public:
  void setScale(unsigned int n);
  void toStart();

//signals:
  //int getFrameNumber();
   // void sliderSingleStep();
};

class SolverDialog : public QDialog
{
  Q_OBJECT
private:
  enum TimeUnits
  {
    SECONDS = 0,
    MINUTES = 1,
    HOURS = 2,
    EARTH_DAYS = 3,
    EARTH_WEEKS = 4,
    EARTH_MONTHES = 5,
    EARTH_YEARS = 6,
    UNITS_NUMBER = 7,
  };
public:
  SolverDialog(QWidget* parent = NULL, const SolutionParameters& solutionParameters = SolutionParameters());
  ~SolverDialog();

public slots:
  void cancel();
  void solve();
  void changedTimeUnits(int idx);
signals:
  void startSolution(const SolutionParameters& solPar);
private:
  SolutionParameters solPar;
  
  QComboBox* solversComboBox;
  QComboBox* timeUnitsComboBox;
  
  RealNumTextEdit* startEdit;
  RealNumTextEdit* endEdit;
  RealNumTextEdit* deltaEdit;

  QPushButton* solveButton;
  QPushButton* cancelButton;

  TimeUnits unitsType;

  static const double unitsVals[UNITS_NUMBER];
  static const QString unitsNames[UNITS_NUMBER];
};

class PlotDialog;

class GraphicViewer : public QWidget
{
  Q_OBJECT
    
  friend class PlotDialog;
public:
  GraphicViewer(QWidget* parent = NULL);
  void clearPlot();
  void addNewPoint(const QPointF& point, bool updateFlag = true);
protected:
  void paintEvent(QPaintEvent *event);
private:
  void drawCoordinateLines();
  void drawPlot();
  
  QVector<QPointF> points;
  double minX, minY, maxX, maxY;
};

class PlotDialog : public QDialog
{
  Q_OBJECT
public:
  PlotDialog(const MathModel* pModel = NULL, QWidget* parent = NULL);
  ~PlotDialog();

  void setModel(const MathModel* pModel);
public slots:
  void cancel();
  void plot();
private slots:
  void functionChanged(int idx);
private:
  QComboBox* valueComboBox;
  GraphicViewer* plotArea;
  QPushButton* cancelButton;
  QPushButton* plotButton;

  QComboBox* firstPlanet;
  QComboBox* secondPlanet;
  QComboBox* thirdPlanet;

  const MathModel* pMathModel;

  QLabel* maxLabel;
  QLabel* minLabel;
  QLabel* avgLabel;
};


class GraphicsOptionDialog : public QDialog
{
  Q_OBJECT
public:
  GraphicsOptionDialog(QWidget* parent = NULL);
signals:
  void changeObjects(int drawFlag);
  void changeTrajectories(int drawFlag);
  void changeCaptions(int drawFlag);

  void changeAnimationSpeed(int mult);
private slots:
  void speedEdit(int mult);
  void objectEdit(int drawFlag);
  void trajectoryEdit(int drawFlag);
  void captionEdit(int drawFlag);
private:
  QCheckBox* drawPlanetsCheckBox;
  QCheckBox* drawTrajectoriesCheckBox;
  QCheckBox* drawCaptionsCheckBox;
  QSpinBox*  animationSpeedEditBox;
};

class PlanetSystemDialog : public QDialog
{
  Q_OBJECT
public:
  PlanetSystemDialog(MathModel* pMathModel, QWidget* parent = NULL);
  void setMathModel(MathModel* pMathModel);
signals:
  void mathModelChanged();
  void planetNameChanged();
private slots:
  void selectPlanet(int idx);

  void xChanged();
  void yChanged();
  void zChanged();

  void vxChanged();
  void vyChanged();
  void vzChanged();

  void massChanged();

  void renamePlanet();
  void newName();
  void addPlanet();
  void removePlanet();

  void radChanged();
  void redChanged();
  void greenChanged();
  void blueChanged();

  void collisionStateChanged(int state);
private:
  QComboBox* planetsComboBox;
  RealNumTextEdit* xEdit;
  RealNumTextEdit* yEdit;
  RealNumTextEdit* zEdit;

  RealNumTextEdit* vxEdit;
  RealNumTextEdit* vyEdit;
  RealNumTextEdit* vzEdit;

  RealNumTextEdit* radEdit;
  RealNumTextEdit* redEdit;
  RealNumTextEdit* greenEdit;
  RealNumTextEdit* blueEdit;

  RealNumTextEdit* massEdit;
  QCheckBox* setCamera;

  MathModel* m_pMathModel;

  QPushButton* addButton;
  QPushButton* renameButton;
  QPushButton* removeButton;

  InputStringDialog* inputStringDialog;
  QCheckBox* planetsCollision;
};



#endif // INTERFACE_H
